package com.gxy.learn.backup.shiroauth.web;

import com.gxy.learn.backup.shiroauth.common.Result;
import com.gxy.learn.backup.shiroauth.shiro.config.JwtConstant;
import com.gxy.learn.backup.shiroauth.shiro.config.JwtVerifyTokenAuxiliary;
import com.gxy.learn.backup.shiroauth.shiro.config.ShiroRealm;
import com.gxy.learn.backup.shiroauth.shiro.utils.JwtUtil;
import com.gxy.learn.backup.shiroauth.vo.LoginReqParam;
import com.gxy.learn.cu.utils.date.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

/**
 * Description权限测试
 * <p>
 * <p>
 * author: Gao xueyong
 * Create at: 2022/1/25 下午14:18
 */
@Slf4j
@RestController
public class LoginController {

    @Autowired
    private ShiroRealm shiroRealm;
    @Autowired
    private CacheManager cacheManager;
    @Autowired
    private JwtVerifyTokenAuxiliary jwtVerifyTokenAuxiliary;

    @PostMapping(value = "/login")
    public Result login(@Valid @RequestBody LoginReqParam reqParam, HttpServletRequest request, HttpServletResponse response) {
        Subject subject = SecurityUtils.getSubject();
        shiroRealm.clearCachedAuthorizationInfo(reqParam.getUsername());
        DateUtils.getCurrentTime_yyyy_MM_dd();
        /**
         * 密码为明码密码
         */
        UsernamePasswordToken token = new UsernamePasswordToken(reqParam.getUsername(), reqParam.getPassword());
        //先验证用户名密码
        subject.login(token);
        //用户名密码验证通过则调用数据有效性校验
        // 根据需求进行数据有效性校验

        //数据有效性校验通过后生成token
        // 生成token
        Cache cache = cacheManager.getCache(JwtConstant.CAPTCHA_CACHE_KEY);
        //生成token版本号
        String versionKey = JwtUtil.loginVersionKey(reqParam.getUsername());
        Integer loginTokenVersion = jwtVerifyTokenAuxiliary.loginVersion(reqParam.getUsername());
        String jwtToken = JwtUtil.sign(reqParam.getUsername(), loginTokenVersion);
//            版本号放入缓存
        cache.put(versionKey, loginTokenVersion);
        response.setHeader(JwtConstant.TOKEN_HEADER_NAME, jwtToken);
        return Result.success("登录成功！");
    }

    /**
     * 退出
     *
     * @return
     */
    @GetMapping("/logout")
    public Result logout(HttpServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        try {
            Object tokenObj = subject.getPrincipals().getPrimaryPrincipal();
            //刷新版本号
            jwtVerifyTokenAuxiliary.refreshLoginVersion(JwtUtil.getUsername(tokenObj.toString()));
            subject.logout();
            return Result.success("登出成功！");
        } catch (Exception e) {
            log.error("刷新版本号错误！");
            return Result.error("登出失败！");
        }

    }

}
